package cn.edu.tju.elm.controller;

import cn.edu.tju.elm.controller.dto.*;
import cn.edu.tju.elm.model.VirtualWallet;
import cn.edu.tju.elm.model.VirtualWalletTransaction;
import cn.edu.tju.elm.service.VirtualWalletService;
import cn.edu.tju.core.model.User;
import cn.edu.tju.core.security.service.UserService;
import cn.edu.tju.core.model.HttpResult;
import cn.edu.tju.core.model.ResultCodeEnum;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.List;
import java.util.Optional;

/**
 * 虚拟钱包控制器
 * 提供钱包管理、充值提现、转账支付等RESTful API
 */
@RestController
@RequestMapping("/api/virtual-wallets")
@Tag(name = "虚拟钱包管理", description = "虚拟钱包的充值、提现、转账、查询等功能")
public class VirtualWalletController {

    @Autowired
    private VirtualWalletService virtualWalletService;
    
    @Autowired
    private UserService userService;

    // ==================== 钱包基础操作 ====================

    /**
     * 根据用户ID查询虚拟钱包
     */
    @GetMapping("/user/{userId}")
    @Operation(summary = "根据用户ID查询虚拟钱包", description = "查询指定用户的虚拟钱包信息")
    public ResponseEntity<HttpResult<WalletInfoResponse>> getVirtualWalletByUserId(@PathVariable Long userId) {
        try {
            Optional<VirtualWallet> wallet = virtualWalletService.getVirtualWalletByUserId(userId);
            if (wallet.isPresent()) {
                WalletInfoResponse response = new WalletInfoResponse(wallet.get());
                return ResponseEntity.ok(HttpResult.success(response));
            } else {
                return ResponseEntity.ok(HttpResult.failure(ResultCodeEnum.NOT_FOUND, "虚拟钱包不存在"));
            }
        } catch (Exception e) {
            return ResponseEntity.ok(HttpResult.failure(ResultCodeEnum.SERVER_ERROR, e.getMessage()));
        }
    }

    /**
     * 根据钱包ID查询虚拟钱包
     */
    @GetMapping("/{walletId:[0-9]+}")
    @Operation(summary = "根据钱包ID查询虚拟钱包", description = "查询指定ID的虚拟钱包信息")
    public ResponseEntity<HttpResult<WalletInfoResponse>> getVirtualWallet(@PathVariable Long walletId) {
        try {
            Optional<VirtualWallet> wallet = virtualWalletService.getVirtualWallet(walletId);
            if (wallet.isPresent()) {
                WalletInfoResponse response = new WalletInfoResponse(wallet.get());
                return ResponseEntity.ok(HttpResult.success(response));
            } else {
                return ResponseEntity.ok(HttpResult.failure(ResultCodeEnum.NOT_FOUND, "虚拟钱包不存在"));
            }
        } catch (Exception e) {
            return ResponseEntity.ok(HttpResult.failure(ResultCodeEnum.SERVER_ERROR, e.getMessage()));
        }
    }

    /**
     * 创建虚拟钱包
     */
    @PostMapping("")
    @Operation(summary = "创建虚拟钱包", description = "为指定用户创建虚拟钱包")
    public ResponseEntity<HttpResult<VirtualWallet>> createVirtualWallet(@RequestParam Long userId) {
        try {
            Optional<User> userOpt = userService.getUserById(userId);
            if (userOpt.isEmpty()) {
                return ResponseEntity.ok(HttpResult.failure(ResultCodeEnum.BAD_REQUEST, "用户不存在"));
            }

            VirtualWallet wallet = virtualWalletService.createVirtualWallet(userOpt.get());
            return ResponseEntity.ok(HttpResult.success(wallet));
        } catch (IllegalArgumentException e) {
            return ResponseEntity.ok(HttpResult.failure(ResultCodeEnum.BAD_REQUEST, e.getMessage()));
        } catch (Exception e) {
            return ResponseEntity.ok(HttpResult.failure(ResultCodeEnum.SERVER_ERROR, e.getMessage()));
        }
    }

    /**
     * 查询余额
     */
    @GetMapping("/{walletId:[0-9]+}/balance")
    @Operation(summary = "查询余额", description = "查询指定钱包的当前余额")
    public ResponseEntity<HttpResult<BigDecimal>> getBalance(@PathVariable Long walletId) {
        try {
            BigDecimal balance = virtualWalletService.getBalance(walletId);
            return ResponseEntity.ok(HttpResult.success(balance));
        } catch (Exception e) {
            return ResponseEntity.ok(HttpResult.failure(ResultCodeEnum.SERVER_ERROR, e.getMessage()));
        }
    }
    // ==================== 充值和提现 ====================

    /**
     * 充值
     */
    @PostMapping("/recharge")
    @Operation(summary = "充值", description = "向钱包充值，自动应用充值返点规则")
    public ResponseEntity<HttpResult<VirtualWalletTransaction>> recharge(@RequestBody WalletRechargeRequest request) {
        try {
            if (request.getAmount() == null || request.getAmount().compareTo(BigDecimal.ZERO) <= 0) {
                return ResponseEntity.ok(HttpResult.failure(ResultCodeEnum.BAD_REQUEST, "充值金额必须大于0"));
            }

            VirtualWalletTransaction transaction = virtualWalletService.recharge(
                request.getWalletId(), 
                request.getAmount(), 
                request.getRemark()
            );
            return ResponseEntity.ok(HttpResult.success(transaction));
        } catch (Exception e) {
            return ResponseEntity.ok(HttpResult.failure(ResultCodeEnum.SERVER_ERROR, "充值失败：" + e.getMessage()));
        }
    }

    /**
     * 提现
     */
    @PostMapping("/withdraw")
    @Operation(summary = "提现", description = "从钱包提现，自动应用提现手续费规则")
    public ResponseEntity<HttpResult<VirtualWalletTransaction>> withdraw(@RequestBody WalletWithdrawRequest request) {
        try {
            if (request.getAmount() == null || request.getAmount().compareTo(BigDecimal.ZERO) <= 0) {
                return ResponseEntity.ok(HttpResult.failure(ResultCodeEnum.BAD_REQUEST, "提现金额必须大于0"));
            }

            VirtualWalletTransaction transaction = virtualWalletService.withdraw(
                request.getWalletId(), 
                request.getAmount(), 
                request.getRemark()
            );
            return ResponseEntity.ok(HttpResult.success(transaction));
        } catch (Exception e) {
            return ResponseEntity.ok(HttpResult.failure(ResultCodeEnum.SERVER_ERROR, "提现失败：" + e.getMessage()));
        }
    }

    // ==================== 转账和支付 ====================

    /**
     * 转账
     */
    @PostMapping("/transfer")
    @Operation(summary = "转账", description = "从一个钱包转账到另一个钱包")
    public ResponseEntity<HttpResult<String>> transfer(@RequestBody WalletTransferRequest request) {
        try {
            if (request.getAmount() == null || request.getAmount().compareTo(BigDecimal.ZERO) <= 0) {
                return ResponseEntity.ok(HttpResult.failure(ResultCodeEnum.BAD_REQUEST, "转账金额必须大于0"));
            }

            boolean success = virtualWalletService.transfer(
                request.getFromWalletId(), 
                request.getToWalletId(), 
                request.getAmount(), 
                request.getOrderId(), 
                request.getRemark()
            );

            if (success) {
                return ResponseEntity.ok(HttpResult.success("转账成功"));
            } else {
                return ResponseEntity.ok(HttpResult.failure(ResultCodeEnum.SERVER_ERROR, "转账失败"));
            }
        } catch (Exception e) {
            return ResponseEntity.ok(HttpResult.failure(ResultCodeEnum.SERVER_ERROR, "转账失败：" + e.getMessage()));
        }
    }

    /**
     * 支付订单（冻结资金）
     */
    @PostMapping("/pay-order")
    @Operation(summary = "支付订单", description = "支付订单，冻结相应金额直到确认收货")
    public ResponseEntity<HttpResult<String>> payOrder(
            @RequestParam Long walletId, 
            @RequestParam BigDecimal amount, 
            @RequestParam Long orderId) {
        try {
            boolean success = virtualWalletService.payOrder(walletId, amount, orderId);
            if (success) {
                return ResponseEntity.ok(HttpResult.success("订单支付成功"));
            } else {
                return ResponseEntity.ok(HttpResult.failure(ResultCodeEnum.SERVER_ERROR, "订单支付失败"));
            }
        } catch (Exception e) {
            return ResponseEntity.ok(HttpResult.failure(ResultCodeEnum.SERVER_ERROR, "订单支付失败：" + e.getMessage()));
        }
    }

    /**
     * 确认收货（扣除冻结资金并转给商家）
     */
    @PostMapping("/confirm-order")
    @Operation(summary = "确认收货", description = "买家确认收货，扣除冻结资金并转给卖家")
    public ResponseEntity<HttpResult<String>> confirmOrder(
            @RequestParam Long buyerWalletId, 
            @RequestParam Long sellerWalletId, 
            @RequestParam BigDecimal amount, 
            @RequestParam Long orderId) {
        try {
            boolean success = virtualWalletService.confirmOrder(buyerWalletId, sellerWalletId, amount, orderId);
            if (success) {
                return ResponseEntity.ok(HttpResult.success("确认收货成功"));
            } else {
                return ResponseEntity.ok(HttpResult.failure(ResultCodeEnum.SERVER_ERROR, "确认收货失败"));
            }
        } catch (Exception e) {
            return ResponseEntity.ok(HttpResult.failure(ResultCodeEnum.SERVER_ERROR, "确认收货失败：" + e.getMessage()));
        }
    }

    /**
     * 取消订单（解冻资金）
     */
    @PostMapping("/cancel-order")
    @Operation(summary = "取消订单", description = "取消订单，解冻冻结的资金")
    public ResponseEntity<HttpResult<String>> cancelOrder(
            @RequestParam Long walletId, 
            @RequestParam BigDecimal amount, 
            @RequestParam Long orderId) {
        try {
            boolean success = virtualWalletService.cancelOrder(walletId, amount, orderId);
            if (success) {
                return ResponseEntity.ok(HttpResult.success("取消订单成功"));
            } else {
                return ResponseEntity.ok(HttpResult.failure(ResultCodeEnum.SERVER_ERROR, "取消订单失败"));
            }
        } catch (Exception e) {
            return ResponseEntity.ok(HttpResult.failure(ResultCodeEnum.SERVER_ERROR, "取消订单失败：" + e.getMessage()));
        }
    }

    /**
     * 退款
     */
    @PostMapping("/refund")
    @Operation(summary = "退款", description = "卖家退款给买家")
    public ResponseEntity<HttpResult<String>> refund(
            @RequestParam Long sellerWalletId, 
            @RequestParam Long buyerWalletId, 
            @RequestParam BigDecimal amount, 
            @RequestParam Long orderId) {
        try {
            boolean success = virtualWalletService.refund(sellerWalletId, buyerWalletId, amount, orderId);
            if (success) {
                return ResponseEntity.ok(HttpResult.success("退款成功"));
            } else {
                return ResponseEntity.ok(HttpResult.failure(ResultCodeEnum.SERVER_ERROR, "退款失败"));
            }
        } catch (Exception e) {
            return ResponseEntity.ok(HttpResult.failure(ResultCodeEnum.SERVER_ERROR, "退款失败：" + e.getMessage()));
        }
    }

    // ==================== 冻结和解冻 ====================

    /**
     * 冻结资金
     */
    @PostMapping("/{walletId:[0-9]+}/freeze")
    @Operation(summary = "冻结资金", description = "冻结钱包中的指定金额")
    public ResponseEntity<HttpResult<String>> freezeAmount(
            @PathVariable Long walletId, 
            @RequestParam BigDecimal amount, 
            @RequestParam(required = false) String remark) {
        try {
            boolean success = virtualWalletService.freezeAmount(walletId, amount, remark);
            if (success) {
                return ResponseEntity.ok(HttpResult.success("冻结资金成功"));
            } else {
                return ResponseEntity.ok(HttpResult.failure(ResultCodeEnum.SERVER_ERROR, "冻结资金失败"));
            }
        } catch (Exception e) {
            return ResponseEntity.ok(HttpResult.failure(ResultCodeEnum.SERVER_ERROR, "冻结资金失败：" + e.getMessage()));
        }
    }

    /**
     * 解冻资金
     */
    @PostMapping("/{walletId:[0-9]+}/unfreeze")
    @Operation(summary = "解冻资金", description = "解冻钱包中的指定金额")
    public ResponseEntity<HttpResult<String>> unfreezeAmount(
            @PathVariable Long walletId, 
            @RequestParam BigDecimal amount, 
            @RequestParam(required = false) String remark) {
        try {
            boolean success = virtualWalletService.unfreezeAmount(walletId, amount, remark);
            if (success) {
                return ResponseEntity.ok(HttpResult.success("解冻资金成功"));
            } else {
                return ResponseEntity.ok(HttpResult.failure(ResultCodeEnum.SERVER_ERROR, "解冻资金失败"));
            }
        } catch (Exception e) {
            return ResponseEntity.ok(HttpResult.failure(ResultCodeEnum.SERVER_ERROR, "解冻资金失败：" + e.getMessage()));
        }
    }

    /**
     * 冻结钱包
     */
    @PostMapping("/{walletId:[0-9]+}/freeze-wallet")
    @PreAuthorize("hasAuthority('ADMIN')")
    @Operation(summary = "冻结钱包", description = "冻结整个钱包，禁止一切操作（仅管理员）")
    public ResponseEntity<HttpResult<String>> freezeWallet(@PathVariable Long walletId) {
        try {
            boolean success = virtualWalletService.freezeWallet(walletId);
            if (success) {
                return ResponseEntity.ok(HttpResult.success("钱包冻结成功"));
            } else {
                return ResponseEntity.ok(HttpResult.failure(ResultCodeEnum.SERVER_ERROR, "钱包冻结失败"));
            }
        } catch (Exception e) {
            return ResponseEntity.ok(HttpResult.failure(ResultCodeEnum.SERVER_ERROR, "钱包冻结失败：" + e.getMessage()));
        }
    }

    /**
     * 解冻钱包
     */
    @PostMapping("/{walletId:[0-9]+}/unfreeze-wallet")
    @PreAuthorize("hasAuthority('ADMIN')")
    @Operation(summary = "解冻钱包", description = "解冻钱包，恢复正常使用（仅管理员）")
    public ResponseEntity<HttpResult<String>> unfreezeWallet(@PathVariable Long walletId) {
        try {
            boolean success = virtualWalletService.unfreezeWallet(walletId);
            if (success) {
                return ResponseEntity.ok(HttpResult.success("钱包解冻成功"));
            } else {
                return ResponseEntity.ok(HttpResult.failure(ResultCodeEnum.SERVER_ERROR, "钱包解冻失败"));
            }
        } catch (Exception e) {
            return ResponseEntity.ok(HttpResult.failure(ResultCodeEnum.SERVER_ERROR, "钱包解冻失败：" + e.getMessage()));
        }
    }

    // ==================== VIP和透支管理 ====================

    /**
     * 设置VIP
     */
    @PostMapping("/{walletId:[0-9]+}/set-vip")
    @PreAuthorize("hasAnyAuthority('ADMIN','USER')")
    @Operation(summary = "设置VIP", description = "将用户设置为VIP并分配透支额度")
    public ResponseEntity<HttpResult<String>> setVip(
            @PathVariable Long walletId) {
        try {
            boolean success = virtualWalletService.setVip(walletId, new BigDecimal("500"));
            if (success) {
                return ResponseEntity.ok(HttpResult.success("设置VIP成功"));
            } else {
                return ResponseEntity.ok(HttpResult.failure(ResultCodeEnum.SERVER_ERROR, "设置VIP失败"));
            }
        } catch (Exception e) {
            return ResponseEntity.ok(HttpResult.failure(ResultCodeEnum.SERVER_ERROR, "设置VIP失败：" + e.getMessage()));
        }
    }

    /**
     * 取消VIP
     */
    @PostMapping("/{walletId:[0-9]+}/cancel-vip")
    @PreAuthorize("hasAnyAuthority('ADMIN','USER')")
    @Operation(summary = "取消VIP", description = "取消用户的VIP资格")
    public ResponseEntity<HttpResult<String>> cancelVip(@PathVariable Long walletId) {
        try {
            boolean success = virtualWalletService.cancelVip(walletId);
            if (success) {
                return ResponseEntity.ok(HttpResult.success("取消VIP成功"));
            } else {
                return ResponseEntity.ok(HttpResult.failure(ResultCodeEnum.SERVER_ERROR, "取消VIP失败"));
            }
        } catch (Exception e) {
            return ResponseEntity.ok(HttpResult.failure(ResultCodeEnum.SERVER_ERROR, "取消VIP失败：" + e.getMessage()));
        }
    }

    /**
     * 还款
     */
    @PostMapping("/{walletId:[0-9]+}/repay")
    @Operation(summary = "还款", description = "偿还透支金额")
    public ResponseEntity<HttpResult<VirtualWalletTransaction>> repay(
            @PathVariable Long walletId, 
            @RequestParam BigDecimal amount) {
        try {
            VirtualWalletTransaction transaction = virtualWalletService.repay(walletId, amount);
            return ResponseEntity.ok(HttpResult.success(transaction));
        } catch (Exception e) {
            return ResponseEntity.ok(HttpResult.failure(ResultCodeEnum.SERVER_ERROR, "还款失败：" + e.getMessage()));
        }
    }

    /**
     * 计算透支利息
     */
    @GetMapping("/{walletId:[0-9]+}/interest")
    @Operation(summary = "计算透支利息", description = "计算当前应付的透支利息")
    public ResponseEntity<HttpResult<BigDecimal>> calculateInterest(@PathVariable Long walletId) {
        try {
            BigDecimal interest = virtualWalletService.calculateInterest(walletId);
            return ResponseEntity.ok(HttpResult.success(interest));
        } catch (Exception e) {
            return ResponseEntity.ok(HttpResult.failure(ResultCodeEnum.SERVER_ERROR, e.getMessage()));
        }
    }

    /**
     * 支付利息
     */
    @PostMapping("/{walletId:[0-9]+}/pay-interest")
    @Operation(summary = "支付利息", description = "支付透支产生的利息")
    public ResponseEntity<HttpResult<VirtualWalletTransaction>> payInterest(@PathVariable Long walletId) {
        try {
            VirtualWalletTransaction transaction = virtualWalletService.payInterest(walletId);
            return ResponseEntity.ok(HttpResult.success(transaction));
        } catch (Exception e) {
            return ResponseEntity.ok(HttpResult.failure(ResultCodeEnum.SERVER_ERROR, "支付利息失败：" + e.getMessage()));
        }
    }

    // ==================== 交易记录查询 ====================

    /**
     * 获取交易记录
     */
    @GetMapping("/{walletId:[0-9]+}/transactions")
    @Operation(summary = "获取交易记录", description = "获取钱包的所有交易记录")
    public ResponseEntity<HttpResult<List<VirtualWalletTransaction>>> getTransactionHistory(@PathVariable Long walletId) {
        try {
            List<VirtualWalletTransaction> transactions = virtualWalletService.getTransactionHistory(walletId);
            return ResponseEntity.ok(HttpResult.success(transactions));
        } catch (Exception e) {
            return ResponseEntity.ok(HttpResult.failure(ResultCodeEnum.SERVER_ERROR, e.getMessage()));
        }
    }

    /**
     * 根据订单ID获取交易记录
     */
    @GetMapping("/transactions/order/{orderId}")
    @Operation(summary = "根据订单ID获取交易记录", description = "获取指定订单相关的所有交易记录")
    public ResponseEntity<HttpResult<List<VirtualWalletTransaction>>> getTransactionsByOrderId(@PathVariable Long orderId) {
        try {
            List<VirtualWalletTransaction> transactions = virtualWalletService.getTransactionsByOrderId(orderId);
            return ResponseEntity.ok(HttpResult.success(transactions));
        } catch (Exception e) {
            return ResponseEntity.ok(HttpResult.failure(ResultCodeEnum.SERVER_ERROR, e.getMessage()));
        }
    }

    /**
     * 根据交易类型获取交易记录
     */
    @GetMapping("/{walletId:[0-9]+}/transactions/type/{transactionType}")
    @Operation(summary = "根据交易类型获取交易记录", description = "获取指定钱包指定类型的交易记录")
    public ResponseEntity<HttpResult<List<VirtualWalletTransaction>>> getTransactionsByType(
            @PathVariable Long walletId, 
            @PathVariable String transactionType) {
        try {
            List<VirtualWalletTransaction> transactions = virtualWalletService.getTransactionsByType(walletId, transactionType);
            return ResponseEntity.ok(HttpResult.success(transactions));
        } catch (Exception e) {
            return ResponseEntity.ok(HttpResult.failure(ResultCodeEnum.SERVER_ERROR, e.getMessage()));
        }
    }
}
